package new_user

import (
	"context"
	"errors"
	"git.mycaigou.com/gfyx/common/rpc_client"
	"git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/common/constants"
	base2 "git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/dto/base"
	pb "git.mycaigou.com/gfyx/micro-gfyx-api/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/base"
	"git.myscrm.cn/golang/stark/v4"
)

type userRepository struct {
}

// NewUserRepository 构造函数
func NewUserRepository() UserRepositoryIface {
	return &userRepository{}
}

// UserList 用户列表
func (r *userRepository) UserList(ctx context.Context, param *base2.UserListParam) ([]*base2.User, *base2.Page, error) {
	if param == nil {
		return nil, nil, errors.New("缺少参数")
	}

	req := &pb.UserListRequest{
		Page: &pb.BasePage{
			Page:     param.Page,
			PageSize: param.PageSize,
		},
		Keyword: param.Keyword,
		Status:  param.Status,
		OrgId:   param.OrgId,
	}

	userList := make([]*base2.User, 0)
	page := &base2.Page{
		Page:     param.Page,
		PageSize: param.PageSize,
	}
	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return nil, nil, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := pb.NewBaseUserServiceClient(conn)
	resp, err := client.UserList(ctx, req)
	if err != nil {
		return nil, nil, err
	}

	if resp == nil {
		return nil, nil, errors.New("获取用户列表失败")
	}

	if resp.Page != nil {
		page.Page = resp.Page.Page
		page.PageSize = resp.Page.PageSize
		page.Total = resp.Page.Total
	}

	for _, u := range resp.List {
		orgs := make([]*base2.OrgItem, 0)
		roles := make([]*base2.RoleItem, 0)
		if u.Orgs != nil {
			for _, o := range u.Orgs {
				orgs = append(orgs, &base2.OrgItem{
					ParentOrgId: o.ParentId,
					OrgName:     o.OrgName,
					OrgId:       o.Id,
					OrgFullName: o.FullName,
				})
			}
		}

		if u.Roles != nil {
			for _, r := range u.Roles {
				roles = append(roles, &base2.RoleItem{
					Id:   r.Id,
					Name: r.RoleName,
				})
			}
		}
		userList = append(userList, &base2.User{
			Id:              u.Id,
			UserName:        u.UserName,
			Position:        u.Position,
			Email:           u.Email,
			Mobile:          u.Mobile,
			Status:          u.Status,
			Orgs:            orgs,
			OrgIds:          []int64{},
			Roles:           roles,
			RoleIds:         []int64{},
			CreatedOn:       u.CreatedOn,
			ModifiedOn:      u.ModifiedOn,
			OrgFullNameList: u.FullNameArray,
		})
	}

	return userList, page, nil
}

// UserSave 新增/更新用户
func (r *userRepository) UserSave(ctx context.Context, param *base2.User) (int64, error) {
	orgs := make([]*pb.OrgItem, 0)
	roles := make([]*pb.RoleItem, 0)
	if len(param.OrgIds) != 0 {
		for _, oId := range param.OrgIds {
			orgs = append(orgs, &pb.OrgItem{
				Id: oId,
			})
		}
	}

	if len(param.RoleIds) != 0 {
		for _, rid := range param.RoleIds {
			roles = append(roles, &pb.RoleItem{
				Id: rid,
			})
		}
	}

	req := &pb.UserSaveRequest{
		User: &pb.BaseUser{
			Id:       param.Id,
			UserName: param.UserName,
			Position: param.Position,
			Mobile:   param.Mobile,
			Email:    param.Email,
			Status:   param.Status,
			Orgs:     orgs,
			Roles:    roles,
			Passwd:   param.Passwd,
		},
	}
	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return 0, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := pb.NewBaseUserServiceClient(conn)
	resp, err := client.UserSave(ctx, req)
	if err != nil {
		return 0, err
	}
	if resp == nil {
		return 0, errors.New("更新用户失败")
	}

	return resp.UserId, nil
}

// UserDelete 删除用户
func (r *userRepository) UserDelete(ctx context.Context, param *base2.UserDeleteParam) (int64, error) {
	req := &pb.UserDeleteRequest{
		LeaveUserId:   param.LeaveUserId,
		ReceiveUserId: param.ReceiveUserId,
	}

	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return 0, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := pb.NewBaseUserServiceClient(conn)
	resp, err := client.UserDelete(ctx, req)
	if err != nil {
		return 0, err
	}
	if resp == nil {
		return 0, errors.New("删除用户失败")
	}

	return resp.UserId, nil
}

// UserForbid 禁止用户
func (r *userRepository) UserForbid(ctx context.Context, param *base2.UserForbidParam) error {
	req := &pb.UserForbidRequest{
		UserId: param.UserId,
		Status: param.Status,
	}

	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := pb.NewBaseUserServiceClient(conn)
	_, err = client.UserForbid(ctx, req)
	if err != nil {
		return err
	}

	return nil
}

// UserAuthorize 账号授权
func (r *userRepository) UserAuthorize(ctx context.Context, param *base2.UserAuthorizeParam) error {
	req := &pb.UserAuthRolesRequest{
		UserId:  param.UserId,
		RoleIds: param.RoleIds,
	}

	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return err
	}
	defer func() {
		_ = conn.Close()
	}()

	client := pb.NewBaseUserServiceClient(conn)
	_, err = client.UserAuthRoles(ctx, req)
	if err != nil {
		return err
	}

	return nil
}

// UserImport 用户导入
func (r *userRepository) UserImport(ctx context.Context, userList []*base2.User) ([]*pb.ImportUserMsg, error) {
	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()

	req := &pb.UserImportUsersRequest{}
	req.List = make([]*pb.ImportUser, 0)
	for _, u := range userList {
		roleList := []*pb.RoleItem{}
		roleItem := &pb.RoleItem{RoleName: u.RoleName}
		roleList = append(roleList, roleItem)

		req.List = append(req.List, &pb.ImportUser{
			UserName:         u.UserName,
			Position:         u.Position,
			Mobile:           u.Mobile,
			Email:            u.Email,
			Role:             u.RoleName,
			Passwd:           u.Passwd,
			OrgFullName:      u.OrgFullName,
			DepartmentHeader: u.DepartmentHeader,
		})
	}

	client := pb.NewBaseUserServiceClient(conn)
	resp, err := client.ImportUsers(ctx, req)
	if err != nil {
		return nil, err
	}

	return resp.MsgList, nil
}

// UserInfo 获取用户信息
func (r *userRepository) UserInfo(ctx context.Context, request *pb.UserInfoRequest) (*pb.UserInfoResponse, error) {
	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := pb.NewBaseUserServiceClient(conn)
	res, err := client.UserInfo(ctx, request)
	if err != nil {
		stark.Logger.Errorf(ctx, "get-user-info, call grpc service request:%+v, err:%s", err.Error())
		return nil, err
	}
	return res, nil
}

// SetPassword 设置用户密码
func (r *userRepository) SetPassword(ctx context.Context, request *pb.ResetPasswordRequest) (*pb.ResetPasswordResponse, error) {
	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := pb.NewBaseUserServiceClient(conn)
	res, err := client.ResetPassword(ctx, request)
	if err != nil {
		stark.Logger.Error(ctx, "set-password-error, call grpc service failed: "+err.Error())
		return nil, err
	}
	return res, nil
}

// UserDetail 账号详情
func (r *userRepository) UserDetail(ctx context.Context, userId int64) (*base2.User, error) {
	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := pb.NewBaseUserServiceClient(conn)
	resp, err := client.UserDetail(ctx, &pb.UserDetailRequest{
		Id: userId,
	})
	if err != nil {
		return nil, err
	}

	if resp == nil || resp.User == nil {
		return nil, errors.New("用户不存在")
	}

	uUser := resp.User
	orgs := make([]*base2.OrgItem, 0)
	roles := make([]*base2.RoleItem, 0)
	if uUser.Orgs != nil {
		for _, o := range uUser.Orgs {
			orgs = append(orgs, &base2.OrgItem{
				ParentOrgId: o.ParentId,
				OrgName:     o.OrgName,
				OrgId:       o.Id,
				OrgFullName: o.FullName,
				AreaCodes:   o.AreaCodes,
			})
		}
	}

	if uUser.Roles != nil {
		for _, o := range uUser.Roles {
			roles = append(roles, &base2.RoleItem{
				Id:   o.Id,
				Name: o.RoleName,
			})
		}
	}

	var user = &base2.User{
		Id:         uUser.Id,
		UserName:   uUser.UserName,
		Position:   uUser.Position,
		Email:      uUser.Email,
		Mobile:     uUser.Mobile,
		Orgs:       orgs,
		Roles:      roles,
		Status:     uUser.Status,
		CreatedOn:  uUser.CreatedOn,
		ModifiedOn: uUser.ModifiedOn,
	}

	return user, nil
}

// ResetPassword 重置用户密码
func (r *userRepository) ResetPassword(ctx context.Context, param *base2.ResetPasswordParam) error {
	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := pb.NewBaseUserServiceClient(conn)
	_, err = client.ResetPassword(ctx, &pb.ResetPasswordRequest{
		UserId:      param.UserId,
		NewPassword: param.Passwd,
	})
	if err != nil {
		return err
	}

	return nil
}

// SetDepartmentHeader 设置负责人/取消负责人
func (r *userRepository) SetDepartmentHeader(ctx context.Context, param *base2.SetDepartmentHeaderParam) error {
	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return err
	}
	defer func() {
		_ = conn.Close()
	}()

	client := pb.NewBaseUserServiceClient(conn)
	resp, err := client.UserSetDepartmentHeader(ctx, &pb.UserSetDepartmentHeaderRequest{
		UserId: param.UserIds,
		OrgId:  param.OrgId,
	})
	if err != nil {
		return err
	}
	if resp == nil || resp.IsSuccess == false {
		return errors.New("负责人设置失败")
	}

	return nil
}

func (r *userRepository) GetAllUserList(ctx context.Context) (*pb.GetAllUserListResponse, error) {
	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		stark.Logger.Errorf(ctx, "GetAllUserList err:%s", err.Error())
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()

	client := pb.NewBaseUserServiceClient(conn)
	res, err := client.GetAllUserList(ctx, &pb.EmptyRequest{})
	if err != nil {
		stark.Logger.Errorf(ctx, "GetAllUserList err:%s", err.Error())
		return nil, err
	}

	return res, nil
}

func (r *userRepository) GetAllUserWithOrganization(ctx context.Context) (*pb.GetAllUserWithOrganizationResponse, error) {
	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()

	client := pb.NewBaseUserServiceClient(conn)
	res, err := client.GetAllUserWithOrganization(ctx, &pb.GetAllUserWithOrganizationRequest{})
	if err != nil {
		stark.Logger.Errorf(ctx, "GetAllUserWithOrganization err:%s", err.Error())
		return nil, err
	}

	return res, nil
}

func (r *userRepository) GetMyResponsibleAreaUserList(ctx context.Context, request *pb.GetMyResponsibleAreaUserListRequest) (*pb.GetMyResponsibleAreaUserListResponse, error) {
	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()

	client := pb.NewBaseUserServiceClient(conn)
	return client.GetMyResponsibleAreaUserList(ctx, request)
}
